﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Chloe;
using lingopen.Entity.BLE;
using lingopen.Entity.System;
using lingopen.IdStrategy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace lingopen.Application.BLE.Implements
{
    public class BLETcpAppService : AdminAppService, IBLETcpAppService
    {
        #region 成员 

        List<BLE_Scan_Log> bles;
        AsyncTcpServer server;
        private LocalLog localLog;
        List<Sys_Config> configs;
        bool IsRead = false;
        static object staticObj = new object();
        int saveLogFrequency = 30;//30秒
        int deleteLog = 1;//天
        int upFrequency = 15;
        int batteryLow = 20;
        int alarmLeaveLastMinutes = 15;
        int alarmSleepLastMinutes = 30;
        int deleteUploadDays = 7;
        int deleteAlarmDays = 30;
        int alarmSleepRange = 10;
        string postUrl = "http://safe.foxconn.com:443/temporaryvisitcheck/service1.asmx/GetguardPositionInfo";
        #endregion

        #region 接口
        public void Start()
        {
            GC.Collect();
            string env = AppContext.BaseDirectory;
            IConfigurationBuilder builder = new ConfigurationBuilder()
                 .SetBasePath(env)
                 .AddJsonFile(Path.Combine("configs", "appsettings.json"), optional: true, reloadOnChange: true)  // Settings for the application
                 .AddJsonFile(Path.Combine("configs", $"appsettings.Production.json"), optional: true, reloadOnChange: true)
                 .AddEnvironmentVariables();

            Globals.Configuration = builder.Build();


            //获取配置信息
            var q = this.DbContext.Query<Sys_Config>().FilterDeletedAndDisabled();
            configs = q.ToList();
            saveLogFrequency = Convert.ToInt32(GetValue("saveLogFrequency")); //记录日志频率 秒
            deleteLog = Convert.ToInt32(GetValue("deleteLog"));//删除扫描记录 天
            upFrequency = Convert.ToInt32(GetValue("UploadFrequency")); //上传频率 每15分钟上传一次
            batteryLow = Convert.ToInt32(GetValue("BatteryLow"));//电量报警阈值
            alarmLeaveLastMinutes = Convert.ToInt32(GetValue("AlarmLeaveLastMinutes"));
            alarmSleepLastMinutes = Convert.ToInt32(GetValue("AlarmSleepLastMinutes"));
            alarmSleepRange = Convert.ToInt32(GetValue("AlarmSleepRange"));
            deleteUploadDays = Convert.ToInt32(GetValue("DeleteUploadDays"));
            deleteAlarmDays = Convert.ToInt32(GetValue("DeleteAlarmDays"));
            postUrl = GetValue("postUrl");

            //初始化成员

            bles = new List<BLE_Scan_Log>();
            string ip = Globals.Configuration["tcp:ip"];
            int port = Convert.ToInt32(Globals.Configuration["tcp:port"]);
            localLog = new LocalLog();

#if !DEBUG
            //初始化 tcp 服务
            server = new AsyncTcpServer(IPAddress.Parse(ip), port);
            server.Encoding = Encoding.UTF8;
            server.ClientConnected +=
              new EventHandler<TcpClientConnectedEventArgs>(server_ClientConnected);
            server.ClientDisconnected +=
              new EventHandler<TcpClientDisconnectedEventArgs>(server_ClientDisconnected);
            server.PlaintextReceived +=
              new EventHandler<TcpDatagramReceivedEventArgs<string>>(server_PlaintextReceived);
            if (!server.IsRunning)
            {
                Init_Duty_Online();//全部更新为离线状态 
                server.Start();
                //$"{ip}:TCP server has been started.".Log();
                Console.WriteLine($"{ip}:{port}监听已启动.");
            }
            //保存log
            Task.Run(() =>
            {
                while (server.IsRunning) //Loop/30秒 存 log 日志
                {
                    try
                    {
                        IsRead = false;
                        lock (staticObj) //锁住操作 不给其他线程干扰
                        {
                            foreach (var item in bles)
                            {
                                //1.更新在线状态
                                Update_Duty_Online(item.IP, true);
                                //2.保存Scan_Log
                                Add_Scan_Log(item);

                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        localLog.LogTxt($@"LogError", ex.Message);
                    }
                    finally
                    {
                        IsRead = true;
                        lock (staticObj) //采集队列
                        {
                            bles.Clear();
                        }
                        Thread.Sleep(saveLogFrequency * 1000); //存log频率
                    }
                }
            });
            //上传 报警处理
            Task.Run(() =>
            {

                while (server.IsRunning) //Loop/15分钟
                {
                    try
                    {
                        IsRead = false;
                        Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " 正在执行上传和报警逻辑,频率{0}分钟", upFrequency);
                        lock (staticObj) //锁住操作 不给其他线程干扰
                        {
                            RunTask();
                        }
                    }
                    catch (Exception ex)
                    {
                        localLog.LogTxt($@"LogError", ex.Message);
                    }
                    finally
                    {
                        IsRead = true;
                        Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " 上传结束");

                        bles.Clear();
                    }
                    Thread.Sleep(upFrequency * 60000); //上传频率 分钟 *60

                }
            });
#endif

        }

        public void Stop()
        {
            if (server != null) server.Stop();
        }
        #endregion

        private void server_PlaintextReceived(object sender, TcpDatagramReceivedEventArgs<string> e)
        {
            try
            {
                //+INQRESULT:CD179CDA4B7B,0,"Jinou_Beacon",4,0D094A696E6F755F426561636F6E,-42
                //\r\n+INQRESULT:<addr>,<addrtype>,<name>,<bctype>,<bcdata>,<rssi>\r\n 
                //参数说明：
                //addr： 搜索到的 BLE 设备的 MAC 地址
                //addrtype: 搜索到的 BLE 设备的地址类型 0:普通地址，1：随机地址。
                //name： 搜索到的 BLE 设备名称，该值有可能为空。
                //bctype： 搜索到的 BLE 设备广播类型。具体广播类型的含义请参考蓝牙技术规范
                //Core_V4.2 中[Vol 2] PartE, 7.7.65.2 章节。
                //0 ADV_IND
                //1 ADV_DIRECT_IND
                //2 ADV_SCAN_IND
                //3 ADV_NONCONN_IND
                //4 SACN_RSP
                //bcdata： 搜索到的 BLE 设备的广播数据。具体广播数据的格式请参考蓝牙技术规
                //范 Core_V4.2 中[Vol 3] Part C 11 章节。
                //rssi: BLE 设备和蓝牙网关之间的信号强度

                //当网关不服务器建立 TCP 连接后，如果 10 秒内没有扫描数据包发送，则会发送一个
                //心跳包，服务器可以根据此心跳包来判断不网关的通信是否正常。
                //\r\n +ACTIVE\r\n
                if (!IsRead) return;

                Console.WriteLine(e.Datagram);

                var data = e.Datagram.Replace("\r\n", "");

                string[] args = data.Split(',');
                if (args.Length != 6) return;
                //if (args[2] == "\"\"") return;
                //if (args[2] != "\"Jinou_Beacon\"") return;

                string clientIp = ((IPEndPoint)e.TcpClient.Client.RemoteEndPoint).Address.ToString();


                if (data.ToUpper().Contains("ACTIVE"))
                {
                    localLog.LogTxt($@"LogTxt\Active\{clientIp}", data);
                    return;
                }


                if (data.ToUpper().Contains("+INQRESULT")) //采集日志
                {
                    localLog.LogTxt($@"LogTxt\InqResult\{clientIp}", clientIp + " " + data);
                    var macs = args[0].Split(':');
                    if (macs.Length != 2) return;
                    int rssi = Convert.ToInt32(args[5]);
                    //采集流程 
                    if (!bles.Where(p => p.IP == clientIp && p.MAC == macs[1]).Any())
                        lock (staticObj) //采集队列
                        {
                            //3.更新剩余电量
                            var rand = new Random();
                            var irand = rand.Next(1, 100);
                            bles.Add(new BLE_Scan_Log() { Battery = irand, IP = clientIp, MAC = macs[1], DeviceAddrType = args[1], DeviceName = args[2].Replace("\"", ""), Rssi = rssi, CreationTime = DateTime.Now });
                        }
                }
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
        }
        private void server_ClientDisconnected(object sender, TcpClientDisconnectedEventArgs e)
        {
            try
            {


                Console.WriteLine(string.Format(CultureInfo.InvariantCulture,
                 "TCP client {0} has disconnected.",
                   e.TcpClient.Client.RemoteEndPoint.ToString()));
                string clientIp = ((IPEndPoint)e.TcpClient.Client.RemoteEndPoint).Address.ToString();
                Update_Duty_Online(clientIp, false);
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
        }
        private void server_ClientConnected(object sender, TcpClientConnectedEventArgs e)
        {
            try
            {

                Console.WriteLine(string.Format(CultureInfo.InvariantCulture,
                  "TCP client {0} has connected.",
                  e.TcpClient.Client.RemoteEndPoint.ToString()));
                string clientIp = ((IPEndPoint)e.TcpClient.Client.RemoteEndPoint).Address.ToString();
                Update_Duty_Online(clientIp, true);
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
        }


        private string GetValue(string code)
        {
            try
            {
                if (configs != null)
                {
                    return configs.FirstOrDefault(p => p.Code == code)?.Value ?? "";
                }
                else return "";
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
                return "";
            }

        }
        public void RunTask()
        {
            try
            {
#if !DEBUG
                //1.全部更新为离线状态 
                Init_Duty_Online();
                //2.找到上传周期内的所有标签信息
                var last_minute_15 = DateTime.Now.AddMinutes(-1 * upFrequency);
                var query_logs = this.DbContext.Query<BLE_Scan_Log>(a => a.CreationTime.Value >= last_minute_15).OrderByDesc(p => p.CreationTime).ToList();//找到15分钟内的所有上传数据做distinct
                List<BLE_Scan_Log> needUpLoads = new List<BLE_Scan_Log>();

                if (query_logs.Any())
                {
                    var top_logs = query_logs.Select(p => p.MAC).Distinct();
                    foreach (var top in top_logs)
                    {
                        var first = query_logs.FirstOrDefault(p => p.MAC == top);
                        if (first == null) continue;
                        needUpLoads.Add(first);
                    }//可以为空
                    localLog.LogTxt("LogTxt", $"上传日志({ needUpLoads.ToJson()}");
                }
                
#else

                string str = "[{\"IP\":\"192.168.1.11\",\"MAC\":\"50000158FF20\",\"Rssi\":-57,\"EmployeeNo\":\"0004\",\"EmployeeName\":\"李四\",\"EmpLocation\":\"测试AP\",\"DeviceAddrType\":\"0\",\"DeviceName\":\"\",\"Battery\":25,\"Id\":\"798dd443202a453d938f6b77c44da741\",\"IsEnabled\":true,\"CreationTime\":\"2018-11-19T14:36:14\",\"IsDeleted\":false},{\"IP\":\"192.168.1.11\",\"MAC\":\"4000014DFF20\",\"Rssi\":-57,\"EmployeeNo\":\"0003\",\"EmployeeName\":\"王三\",\"EmpLocation\":\"测试AP\",\"DeviceAddrType\":\"0\",\"DeviceName\":\"\",\"Battery\":88,\"Id\":\"bf8fb917835a4778bb11b21ed1042ce5\",\"IsEnabled\":true,\"CreationTime\":\"2018-11-19T14:36:14\",\"IsDeleted\":false},{\"IP\":\"192.168.1.11\",\"MAC\":\"C30687BBD0B4\",\"Rssi\":-66,\"EmployeeNo\":\"0002\",\"EmployeeName\":\"李二\",\"EmpLocation\":\"测试AP\",\"DeviceAddrType\":\"0\",\"DeviceName\":\"Jinou_Beacon\",\"Battery\":2,\"Id\":\"e7c9110d0ad5467fb768b5987fc394c2\",\"IsEnabled\":true,\"CreationTime\":\"2018-11-19T14:36:14\",\"IsDeleted\":false}]";

                var needUpLoads = str.FromJson<List<BLE_Scan_Log>>();
#endif

                //1.上传记录
                Add_BLE_API(needUpLoads);

                //3.更新电量+低电量报警
                Add_Emp_Battery(needUpLoads);

                ////4.当前上传周期中的人数少于岗位预设值，取上1个上传周期的所有在岗人员和当前列表进行比对，比对出脱岗的人员进行报警 
                Alarm_Leave(needUpLoads); //返回报警的人  

                ////5.当前上传周期中的某个岗位连续30分钟RSSI曲线平直，在进行睡眠报警
                Alarm_Sleep(needUpLoads);//返回报警的人  
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
        }



        #region 数据库操作OR中央数据库操作
        /// <summary>
        /// 电量报警记录
        /// </summary>
        /// <remarks>BLE标签电量低于20%，发送预警信息给中央安全DB (API中会包含电量报警栏，低于20%则每次发送过去的数据中电量部分则为1，不需要精确告知对方电量具体百分比，仅考量低于或高于20%的状态)</remarks>
        /// <param name="item"></param>
        private void Alarm_BatteryLow(BLE_Scan_Log item, int? battery)
        {
            try
            {
                if (battery == null) return;




            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
            //上传 更新 SyncTime
        }
        /// <summary>
        /// 脱岗报警记录
        /// </summary>
        /// <param name="item"></param>
        private void Alarm_Leave(List<BLE_Scan_Log> last_list_15)
        {
            try
            {
                DateTime now = DateTime.Now;
                var last_minute_15 = DateTime.Now.AddMinutes(-1 * upFrequency); //本周起的起始时间
                var last_minute_15x2 = DateTime.Now.AddMinutes(-1 * (alarmLeaveLastMinutes + 1) * upFrequency);//上2个周期中的起始时间
                                                                                                               //找前N个上传周期中的 岗位信息
                var last_list_15x2_query = this.DbContext.Query<BLE_Transfer_Api>(a => a.SyncTime.Value >= last_minute_15x2 && a.SyncTime < last_minute_15).OrderByDesc(p => p.SyncTime).ToList();
                if (!last_list_15x2_query.Any()) return;//如果还没有开始采集就跳出
                //从上一个周期中的数据中找出所有岗位ip
                var loop_dutys = last_list_15x2_query.Select(p => p.IP).Distinct();
                //本轮采集的岗位ip  
                List<string> current_ips = null;
                if (last_list_15 != null && last_list_15.Any())
                {

                    current_ips = last_list_15.Select(a => a.IP).Distinct().ToList();
                }
                ///轮寻报警
                foreach (var duty in loop_dutys) //在上一次的上传中期中岗位做轮寻
                {
                    if (last_list_15 != null && last_list_15.Any() && current_ips.Contains(duty)) //本轮未全部脱岗的岗位
                    {
                        //找到需要验证的岗位信息                        
                        var duty_db = this.DbContext.Query<BLE_Duty>(p => p.Code == duty).FirstOrDefault();
                        if (duty_db != null)//对比数量
                        {
                            var ip_macs = (from p in last_list_15
                                           where p.IP == duty
                                           select new { p.IP, p.MAC }).ToList();

                            if (duty_db.DutyCount > ip_macs.Count)//需要报警
                            {

                                var needAlarms = last_list_15x2_query.Where(p => p.IP == duty && !ip_macs.Where(a => a.MAC == p.MAC).Any()).ToList();//找出缺席的mac

                                foreach (var needAlarm in needAlarms)
                                {
                                    //需要报警的记录
                                    var insert = new BLE_Alarm_Leave()
                                    {
                                        MAC = needAlarm.MAC,
                                        AlarmStatus = "1",
                                        Battery = needAlarm.Battery,
                                        CreationTime = needAlarm.CreationTime,
                                        DeviceAddrType = needAlarm.DeviceAddrType,
                                        DeviceName = needAlarm.DeviceName,
                                        EmpLocation = needAlarm.EmpLocation,
                                        EmployeeName = needAlarm.EmployeeName,
                                        EmployeeNo = needAlarm.EmployeeNo,
                                        IP = needAlarm.IP,
                                        Rssi = needAlarm.Rssi,
                                        IsDeleted = false,
                                        IsEnabled = true,
                                        Id = IdHelper.CreateGuid(),
                                    };
                                    string status = "";
                                    try
                                    {
                                        string pars = $"EmployeeNo={insert.EmployeeNo}&EmployeeName={insert.EmployeeName}&EmpLocation={insert.EmpLocation}&DateTime={insert.CreationTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}&DeviceAddr={insert.MAC}&DeviceAddrType={insert.DeviceAddrType}&AlarmStatus={insert.AlarmStatus}&DeviceName={""}&DeviceRssi={insert.Rssi}";
                                        var xml = HttpCrossDomain.POST(postUrl, pars);
                                        xml = xml.Replace("xmlns=\"http://tempuri.org/\"", "");
                                        status = XmlHelper.XmlDeserialize<string>(xml);
                                    }
                                    catch (Exception ex)
                                    {
                                        status = ex.Message;
                                        localLog.LogTxt($@"LogError", ex.Message);
                                    }
                                    finally
                                    {
                                        insert.IsSync = true;
                                        insert.SyncTime = now;
                                        insert.SyncStatus = status;
                                        this.DbContext.Insert(insert);
                                    }
                                }
                            }


                        }

                    }
                    else //本轮已全部脱岗的岗位
                    {
                        foreach (var needAlarm in last_list_15x2_query)
                        {
                            var insert = new BLE_Alarm_Leave()
                            {
                                MAC = needAlarm.MAC,
                                AlarmStatus = "1",
                                Battery = needAlarm.Battery,
                                CreationTime = needAlarm.CreationTime,
                                DeviceAddrType = needAlarm.DeviceAddrType,
                                DeviceName = needAlarm.DeviceName,
                                EmpLocation = needAlarm.EmpLocation,
                                EmployeeName = needAlarm.EmployeeName,
                                EmployeeNo = needAlarm.EmployeeNo,
                                IP = needAlarm.IP,
                                Rssi = needAlarm.Rssi,
                                IsDeleted = false,
                                IsEnabled = true,
                                Id = IdHelper.CreateGuid(),
                            };
                            string status = "";
                            try
                            {
                                string pars = $"EmployeeNo={insert.EmployeeNo}&EmployeeName={insert.EmployeeName}&EmpLocation={insert.EmpLocation}&DateTime={insert.CreationTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}&DeviceAddr={insert.MAC}&DeviceAddrType={insert.DeviceAddrType}&AlarmStatus={insert.AlarmStatus}&DeviceName={""}&DeviceRssi={insert.Rssi}";
                                var xml = HttpCrossDomain.POST(postUrl, pars);
                                xml = xml.Replace("xmlns=\"http://tempuri.org/\"", "");
                                status = XmlHelper.XmlDeserialize<string>(xml);
                            }
                            catch (Exception ex)
                            {
                                status = ex.Message;
                                localLog.LogTxt($@"LogError", ex.Message);
                            }
                            finally
                            {
                                insert.IsSync = true;
                                insert.SyncTime = now;
                                insert.SyncStatus = status;
                                this.DbContext.Insert(insert);
                            }

                        }

                    }

                }

                //删除30天的上传记录 deleteAlarmDays
                this.DbContext.Delete<BLE_Alarm_Leave>(a => DateTime.Now.Day == DateTime.Now.AddDays(-1 * deleteAlarmDays).Day);//删除前N天的日志文件

            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }

            //上传 更新 SyncTime
        }
        /// <summary>
        /// 睡眠报警记录
        /// </summary>
        /// <param name="item"></param>
        private void Alarm_Sleep(List<BLE_Scan_Log> last_list_15)
        {
            try
            {
                DateTime now = DateTime.Now;
                //某个人员连续30分钟RSSI曲线变化较小，则提醒睡眠预警
                var last_minute_15x2 = DateTime.Now.AddMinutes(-1 * alarmSleepLastMinutes);//上2个周期中的起始时间
                                                                                           //AlarmSleepRange 波动范围
                var last_list_30 = this.DbContext.Query<BLE_Transfer_Api>(a => a.SyncTime.Value >= last_minute_15x2 && a.SyncTime < DateTime.Now).OrderBy(p => p.SyncTime).ToList();

                var max_mins = from p in last_list_30
                               group p by p.MAC into g
                               select new { MAC = g.Key, MAX_Rssi = g.Max(p => p.Rssi), Min_Rssi = g.Min(p => p.Rssi) };
                var need_macs = from p in max_mins
                                where (p.MAX_Rssi - p.Min_Rssi) <= alarmSleepRange  //最大波动小于预设值 则需要报警
                                select new { p.MAC, p.MAX_Rssi, p.Min_Rssi };
                var need_Alarms = last_list_15.Where(p => need_macs.Where(a => a.MAC == p.MAC).Any());

                foreach (var needAlarm in need_Alarms)
                {
                    var max_min_rssi = need_macs.FirstOrDefault(p => p.MAC == needAlarm.MAC);
                    if (max_min_rssi == null) continue;
                    //报警记录 
                    var insert = new BLE_Alarm_Sleep()
                    {
                        MAC = needAlarm.MAC,
                        AlarmStatus = "2",
                        Battery = needAlarm.Battery,
                        CreationTime = DateTime.Now,// needAlarm.CreationTime,
                        DeviceAddrType = needAlarm.DeviceAddrType,
                        DeviceName = needAlarm.DeviceName,
                        EmpLocation = needAlarm.EmpLocation,
                        EmployeeName = needAlarm.EmployeeName,
                        EmployeeNo = needAlarm.EmployeeNo,
                        IP = needAlarm.IP,
                        Rssi = needAlarm.Rssi,
                        IsDeleted = false,
                        IsEnabled = true,
                        MaxRssi = max_min_rssi.MAX_Rssi,
                        MinRssi = max_min_rssi.Min_Rssi,
                        Id = IdHelper.CreateGuid(),
                    };
                    string status = "";
                    try
                    {
                        string pars = $"EmployeeNo={insert.EmployeeNo}&EmployeeName={insert.EmployeeName}&EmpLocation={insert.EmpLocation}&DateTime={insert.CreationTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}&DeviceAddr={insert.MAC}&DeviceAddrType={insert.DeviceAddrType}&AlarmStatus={insert.AlarmStatus}&DeviceName={""}&DeviceRssi={insert.Rssi}";
                        var xml = HttpCrossDomain.POST(postUrl, pars);
                        xml = xml.Replace("xmlns=\"http://tempuri.org/\"", "");
                        status = XmlHelper.XmlDeserialize<string>(xml);
                    }
                    catch (Exception ex)
                    {
                        status = ex.Message;
                        localLog.LogTxt($@"LogError", ex.Message);
                    }
                    finally
                    {
                        insert.IsSync = true;
                        insert.SyncTime = now;
                        insert.SyncStatus = status;
                        this.DbContext.Insert(insert);
                    }

                }

                //删除30天的上传记录 deleteAlarmDays
                this.DbContext.Delete<BLE_Alarm_Sleep>(a => DateTime.Now.Day == DateTime.Now.AddDays(-1 * deleteAlarmDays).Day);//删除前N天的日志文件
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }

            //上传 更新 SyncTime
        }




        /// <summary>
        /// 上传API记录 //每15分钟发一次
        /// </summary>
        /// <param name="item"></param>
        private void Add_BLE_API(List<BLE_Scan_Log> last_list_15)
        {
            try
            {
                DateTime now = DateTime.Now;
                foreach (var needAlarm in last_list_15)
                {
                    var insert = new BLE_Transfer_Api()
                    {
                        MAC = needAlarm.MAC,
                        AlarmStatus = "0",
                        Battery = needAlarm.Battery,
                        CreationTime = DateTime.Now,// needAlarm.CreationTime,
                        DeviceAddrType = needAlarm.DeviceAddrType,
                        DeviceName = needAlarm.DeviceName,
                        EmpLocation = needAlarm.EmpLocation,
                        EmployeeName = needAlarm.EmployeeName,
                        EmployeeNo = needAlarm.EmployeeNo,
                        IP = needAlarm.IP,
                        Rssi = needAlarm.Rssi,
                        IsDeleted = false,
                        IsEnabled = true,
                        Id = IdHelper.CreateGuid(),
                    };

                    string status = "";
                    try
                    {
                        string pars = $"EmployeeNo={insert.EmployeeNo}&EmployeeName={insert.EmployeeName}&EmpLocation={insert.EmpLocation}&DateTime={insert.CreationTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}&DeviceAddr={insert.MAC}&DeviceAddrType={insert.DeviceAddrType}&AlarmStatus={insert.AlarmStatus}&DeviceName={""}&DeviceRssi={insert.Rssi}";
                        var xml = HttpCrossDomain.POST(postUrl, pars);
                        xml = xml.Replace("xmlns=\"http://tempuri.org/\"", "");
                        status = XmlHelper.XmlDeserialize<string>(xml);
                    }
                    catch (Exception ex)
                    {
                        status = ex.Message;
                        localLog.LogTxt($@"LogError", ex.Message);
                    }
                    finally
                    {
                        insert.SyncTime = now;
                        insert.IsSync = true;
                        insert.SyncStatus = status;
                        this.DbContext.Insert(insert);
                    }
                }
                //删除7天的上传记录 deleteUploadDays 
                this.DbContext.Delete<BLE_Transfer_Api>(a => DateTime.Now.Day == DateTime.Now.AddDays(-1 * deleteUploadDays).Day);//删除前N天的日志文件
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
            //上传 更新 SyncTime
        }


        /// <summary>
        /// 保存log记录 //每10秒阻塞线程进行记录log
        /// </summary>
        /// <param name="item"></param>
        private void Add_Scan_Log(BLE_Scan_Log insrt)
        {
            try
            {
                var query_Duty = this.DbContext.Query<BLE_Duty>().FirstOrDefault(p => p.Code == insrt.IP);
                if (query_Duty != null)
                {
                    var query_Emp = this.DbContext.Query<BLE_Emp_Card>().FirstOrDefault(p => p.MAC == insrt.MAC);
                    if (query_Emp != null)
                    {
                        var insert = new BLE_Scan_Log();
                        insert.IP = insrt.IP;
                        insert.Id = IdHelper.CreateGuid();
                        insert.MAC = insrt.MAC;
                        insert.Rssi = insrt.Rssi;
                        insert.IsEnabled = true;
                        insert.CreationTime = insrt.CreationTime;
                        insert.Battery = insrt.Battery;
                        insert.EmployeeNo = query_Emp.Code;
                        insert.EmployeeName = query_Emp.Name;
                        insert.EmpLocation = query_Duty.Name;
                        insert.DeviceAddrType = insrt.DeviceAddrType;
                        insert.DeviceName = insrt.DeviceName;

                        this.DbContext.Insert(insert);

                        this.DbContext.Delete<BLE_Scan_Log>(a => DateTime.Now.Day == DateTime.Now.AddDays(-1 * deleteLog).Day);//删除前N天的日志文件
                    }
                }
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex + "");
            }
            //上传 更新 SyncTime
        }


        private void Init_Duty_Online()
        {
            try
            {
                this.DbContext.Update<BLE_Duty>(a => true, a => new BLE_Duty() { IsOnline = false });
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }

        }
        private void Update_Duty_Online(string ip, bool online)
        {
            try
            {
                Console.WriteLine("Update_Duty_Online(ip:{0},onlien:{1}", ip, online);
                this.DbContext.Update<BLE_Duty>(a => a.Code == ip, a => new BLE_Duty() { IsOnline = online });
            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
        }
        private void Add_Emp_Battery(List<BLE_Scan_Log> logs)
        {
            try
            {
                DateTime now = DateTime.Now;
                foreach (var item in logs)
                {
                    if (item.Battery == null) continue;
                    this.DbContext.Update<BLE_Emp_Card>(a => a.MAC == item.MAC, a => new BLE_Emp_Card() { Battery = item.Battery });
                    if (item.Battery <= batteryLow)
                    {
                        //报警记录
                        var insert = new BLE_Alarm_Battery()
                        {
                            MAC = item.MAC,
                            AlarmStatus = "3",
                            Battery = item.Battery,
                            CreationTime = item.CreationTime,
                            DeviceAddrType = item.DeviceAddrType,
                            DeviceName = item.DeviceName,
                            EmpLocation = item.EmpLocation,
                            EmployeeName = item.EmployeeName,
                            EmployeeNo = item.EmployeeNo,
                            IP = item.IP,
                            Rssi = item.Rssi,
                            IsDeleted = false,
                            IsEnabled = true,
                            Id = IdHelper.CreateGuid(),
                        };

                        string status = "";
                        try
                        {
                            string pars = $"EmployeeNo={insert.EmployeeNo}&EmployeeName={insert.EmployeeName}&EmpLocation={insert.EmpLocation}&DateTime={insert.CreationTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}&DeviceAddr={insert.MAC}&DeviceAddrType={insert.DeviceAddrType}&AlarmStatus=3&DeviceName={""}&DeviceRssi={insert.Rssi}";
                            var xml = HttpCrossDomain.POST(postUrl, pars);
                            xml = xml.Replace("xmlns=\"http://tempuri.org/\"", "");
                            status = XmlHelper.XmlDeserialize<string>(xml);
                        }
                        catch (Exception ex)
                        {
                            status = ex.Message;
                            localLog.LogTxt($@"LogError", ex.Message);
                        }
                        finally
                        {
                            insert.IsSync = true;
                            insert.SyncTime = now;
                            insert.SyncStatus = status;
                            this.DbContext.Insert(insert);
                        }

                        //Alarm_BatteryLow(item, item.Battery);
                    }
                }



            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
            }
        }
        private List<BLE_Duty> Get_Dutys()
        {
            try
            {
                var ret = DbContext.Query<BLE_Duty>().FilterDeleted().ToList();
                return ret;

            }
            catch (Exception ex)
            {
                localLog.LogTxt($@"LogError", ex.Message);
                return null;
            }
        }

        #endregion
    }
}
